#include "StdTcp.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "StdThread.h"
#include "ClientFunc.h"
#define ip "192.168.192.128"
#include "FileSystem.h"
#define SERVER_PORT 8082

static char MyName[NameSize];
FileSys *fs;       // 文件系统


// char key[26] = "qazwsxedcrfvtgbyhnujmikolp";

/* 数据接收分析 (专门负责读) */
void AnalysisRecy(MSG *m)
{
    switch (m->flag)
    {
    case CHAT:
    //case BROADCAST:
        // printf("接收到来自|%s|的消息：%s\n", m->FromName, m->Content);
        if (strcmp(m->Content, "该用户不是你的好友\n") == 0)
        {
            printf("%s", m->Content);
        }
        else
        {
            PrivateChatFace(m, MyName);
            int count = 0;
            char **result = Split(m->Content, ",", &count);
            int i = 0;
            int flag = 0; // 左右打印的标志位
            for (int i = 0; i < count; i++)
            {

                if (i % 3 == 0)
                {
                    if (strcmp(result[i], MyName) == 0)
                    {
                        flag = 0;
                    }
                    else
                    {
                        flag = 1;
                    }
                }
                MessageShow(result[i], flag);
                if ((i % 3) == 2)
                {
                    printf("\n");
                }
            }
        }
        break;
    case ONLINELIST:
        ShowOnlineList(m);
        break;
    case SENDFILE:
        WriteToLocal(m);
        break;
    case UPLOAD:
        if (strcmp(m->Content, "UPDATEOK") == 0)
        {
            printf("上传文件成功\n");
        }
        break;
    case FILELIST:
        ShowFIleList(m);
        break;
    case ADDFRIEND:
        printf("%s", m->Content);
        break;
    case DELFRIEND:
        printf("%s", m->Content);
        break;
    case SHOWFRIEND:
    {
        printf("%s\n", m->Content);
        break;
    }
    case FRIENDREQUEST:
    {
        printf("%s\n", m->Content);
        break;
    }
    case ISFREIEND:
    {
        printf("%s\n", m->Content);
        break;
    }
    case GREATEGROUP:
        printf("%s\n", m->Content);
        break;
    case DELETEGROUP:
        printf("%s\n", m->Content);
        break;
    case JOINGROUP:
        printf("%s\n", m->Content);
        break;
    case LEAVEGROUP:
        printf("%s\n", m->Content);
        break;
    case CHATGROUP:
    {
        if ((strcmp(m->Content, "该群不存在\n") == 0) || (strcmp(m->Content, "您不在该群聊！\n") == 0))
        {
            printf("%s", m->Content);
        }
        else
        {
            GroupChatFace(m);
            int count = 0;
            char **result = Split(m->Content, ",", &count);
            int i = 0;
            int flag = 0; // 左右打印的标志位
            for (int i = 0; i < count; i++)
            {

                if (i % 3 == 0)
                {
                    if (strcmp(result[i], MyName) == 0)
                    {
                        flag = 0;
                    }
                    else
                    {
                        flag = 1;
                    }
                }
                MessageShow(result[i], flag);
                if ((i % 3) == 2)
                {
                    printf("\n");
                }
            }
        }
        break;
    }
    case DOWNLOAD:
    {
        if (strcmp(m->Content, "文件不存在！\n") == 0)
        {
            printf("%s", m->Content);
        }
        else
        {
            int size = 0;
            
            memcpy(&size, m->Content, 4);
            if (size == -1)
            {
                printf("下载完成！\n");
                break;
            }
            char fileName[NameSize] = {0};
            strcpy(fileName,m->Content + 4);
            WriteFileToFs(fs,MyName, fileName, m->Content + 24, size);
        }

        break;
    }
    default:
        break;
    }
}

/* 线程函数 实现读写分离 */
void *ThreadHandle(void *arg)
{
    TcpC *c = (TcpC *)arg;
    while (1)
    {
        MSG m;
        if (TcpClientRecv(c, &m, sizeof(m)) == false)
        {
            printf("读线程接受错误!\n");
            exit(-1);
        }
        AnalysisRecy(&m);
    }
}

void LoginSignUp(TcpC *c)
{
    while (1)
    {
        int choice = LoginFace();
        MSG m;
        switch (choice)
        {
        case LOGIN:
            m = Login(MyName);
            
            TcpClientSend(c, &m, sizeof(MSG));
            if (TcpClientRecv(c, &m, sizeof(MSG)) == false)
                exit(-1);
            if (IsLoginSuccess(&m) == true)
                return;
            break;
        case SIGNUP:
            m = SignUp(MyName);
            TcpClientSend(c, &m, sizeof(MSG));
            if (TcpClientRecv(c, &m, sizeof(MSG)) == false)
                exit(-1);
            if (IsSignUpSuccess(&m) == true)
                return;
            break;
        default:
            break;
        }
        sleep(2);
        system("clear");
    }
}

void SendFileToServer(MSG *m, TcpC *c)
{
    char* filesize = GetFileSize(m->Content);  //文件总大小
    char *fileName = GetFileNameFromPath(m->Content);
    PackFile *pf = PacketFileInit(m->Content);

    memset(m->Content, 0, sizeof(m->Content));
    strcpy(m->Content + 4, fileName);
    int size = 1000;
    int count = 0;
    int nowsize = 0;
    while (IsFileEnd(pf) == false)
    {
        nowsize += size;
        ReadFromFile(pf, m->Content + 24, &size);
        // 填入读取的文件内容大小
        memcpy(m->Content, &size, sizeof(int));
        TcpClientSend(c, m, sizeof(MSG));
        count++;
        printf("msg flag : %d   这是第%d包数据,大小:%d 下载进度:[%d%%]\r", m->flag, count, size, (nowsize / atoi(filesize)) * 100);
    }
    printf("\n");
    fflush(stdout);
    free(filesize);

    // 传输结束
    size = -1;
    memcpy(m->Content, &size, sizeof(int));
    TcpClientSend(c, m, sizeof(MSG));
    free(fileName);
    ClearPacketFile(pf);
}

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        printf("参数数量不对\n");
        return -1;
    }

    fs = FileSystemInit("./local");// 本地文件系统初始化

    TcpC *c = TcpClientInit(argv[1], atoi(argv[2]));

    /* 注册登录 */
    LoginSignUp(c);

    CreateNewDirInFs(fs, MyName);  //创建本地文件夹

    

    Thread *t = ThreadInit(ThreadHandle, c);

    while (1)
    {
        int choice = Interface();
        MSG m;
        switch (choice)
        {
        case CHAT: /* 私聊 */
            while (1)
            {
                int flag = 0;
                m = ChatToClient(); // 最后发出去的就是这个结构体
                strcpy(m.FromName, MyName);
                TcpClientSend(c, &m, sizeof(m));
                printf("是否退出(1/0):");
                scanf("%d", &flag);
                if (flag == 1)
                {
                    break;
                }
            }

            break;
        //case BROADCAST: /* 广播 */
            // m = ChatBroadCast();
            // strcpy(m.FromName, MyName);
            // TcpClientSend(c, &m, sizeof(m));
            // break;
        case ONLINELIST: /* 查看在线用户 */
            m = GetServerOnlineList();
            strcpy(m.FromName, MyName);
            TcpClientSend(c, &m, sizeof(m));
            break;
        case SENDFILE:
            m = SendFile();
            strcpy(m.FromName, MyName);
            SendFileToServer(&m, c);
            break;
        case MYCLOUD:
        {
            while (1)
            {
                int flag = 0;
                int choice = CloudInterface();
                switch (choice)
                {
                case FILELIST:
                {
                    MSG m;
                    strcpy(m.FromName, MyName);
                    m.flag = FILELIST;
                    TcpClientSend(c, &m, sizeof(m));
                    break;
                }
                case UPLOAD:
                {
                    MSG m = UpLoadFile();
                    strcpy(m.FromName, MyName);
                    SendFileToServer(&m, c);
                    break;
                }
                case DOWNLOAD:
                {
                    MSG m = DownloadFile();
                    strcpy(m.FromName, MyName);
                    TcpClientSend(c, &m, sizeof(m));
                    break;
                }
                default:
                {
                    flag = 1;
                    break;
                }
                }
                if (flag == 1)
                {
                    break;
                }
            }
            break;
        }
        case FRIEND:
            while (1)
            {
                int flag = 0;
                int choice = FriendFace();
                switch (choice)
                {
                case ADDFRIEND:
                {
                    MSG m = AddFriend();
                    strcpy(m.FromName, MyName);
                    TcpClientSend(c, &m, sizeof(m));
                    break;
                }

                // case ISFRIEND:
                //     int choice = IsFriendOk();
                case DELFRIEND:
                {
                    MSG m = DelFriend();
                    strcpy(m.FromName, MyName);
                    TcpClientSend(c, &m, sizeof(m));
                    break;
                }
                case SHOWFRIEND:
                {
                    MSG m;
                    strcpy(m.FromName, MyName);
                    m.flag = SHOWFRIEND;
                    TcpClientSend(c, &m, sizeof(m));
                    break;
                }
                case FRIENDREQUEST:
                {
                    MSG m;
                    strcpy(m.FromName, MyName);
                    m.flag = FRIENDREQUEST;
                    TcpClientSend(c, &m, sizeof(m));
                    break;
                }
                case ISFREIEND:
                {
                    MSG m = IsFriendOk();
                    strcpy(m.FromName, MyName);
                    TcpClientSend(c, &m, sizeof(m));
                    break;
                }

                default:
                    flag = 1;
                    break;
                }
                if (flag == 1)
                {
                    break;
                }
            }

            break;
        case GROUPCHAT:
        {
            while (1)
            {
                int flag = 0;
                int choice = GroupManageFace();
                switch (choice)
                {
                case GREATEGROUP:
                {
                    MSG m = GreateGroup();
                    strcpy(m.FromName, MyName);
                    TcpClientSend(c, &m, sizeof(m));
                    break;
                }
                case DELETEGROUP:
                {
                    MSG m = DeleteGroup();
                    strcpy(m.FromName, MyName);
                    TcpClientSend(c, &m, sizeof(m));
                    break;
                }
                case JOINGROUP:
                {
                    MSG m = JoinGroup();
                    strcpy(m.FromName, MyName);
                    TcpClientSend(c, &m, sizeof(m));
                    break;
                }
                case LEAVEGROUP:
                {
                    MSG m = LeaveGroup();
                    strcpy(m.FromName, MyName);
                    TcpClientSend(c, &m, sizeof(m));
                    break;
                }
                case CHATGROUP:
                {
                    while (1)
                    {
                        int flag = 0;
                        MSG m = ChatGroup();
                        strcpy(m.FromName, MyName);
                        TcpClientSend(c, &m, sizeof(m));
                        sleep(1);
                        printf("\n是否退出(1/0):");
                        scanf("%d", &flag);
                        if (flag == 1)
                        {
                            break;
                        }
                    }
                    break;
                }
                default:
                    flag = 1;
                    break;
                }
                if (flag == 1)
                {
                    break;
                }
                sleep(2);
            }
            break;
        }
        default:
            break;
        }
    }
    return 0;
}
